package com.qf.mpswaggershiro.order.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qf.mpswaggershiro.order.entity.OrderItem;
import com.qf.mpswaggershiro.order.entity.Orders;
import com.qf.mpswaggershiro.order.mapper.OrdersMapper;
import com.qf.mpswaggershiro.order.service.IOrderItemService;
import com.qf.mpswaggershiro.order.service.IOrdersService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qf.mpswaggershiro.product.entity.ProductComments;
import com.qf.mpswaggershiro.product.entity.ProductSku;
import com.qf.mpswaggershiro.product.service.IProductCommentsService;
import com.qf.mpswaggershiro.product.service.IProductSkuService;
import com.qf.mpswaggershiro.shopcart.entity.ShoppingCart;
import com.qf.mpswaggershiro.shopcart.service.IShoppingCartService;
import com.qf.mpswaggershiro.utils.Constants;
import com.qf.mpswaggershiro.weixin.WxPayUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 订单  服务实现类
 * </p>
 *
 * @author cui
 * @since 2023-02-17
 */
@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements IOrdersService {
@Autowired
IProductCommentsService productCommentsService;
@Autowired
IProductSkuService productSkuService;
@Autowired
IShoppingCartService shoppingCartService;
@Autowired
IOrderItemService orderItemService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Map<String, Object> add(String cids, Orders orders) throws Exception {
        // 过滤cids可能存在的#
        cids = cids.replaceAll("#","");
        //1.查询用户购物车中对应商品套餐库存数量是否足够
        //如果库存够,继续下单流程;如果不够库存不足,直接抛出异常(如何一个商品的不足都算失败)
        List<ShoppingCart> shoppingCartList = shoppingCartService.list(new QueryWrapper<ShoppingCart>().in("user_id", cids));
        // 验证库存量
        checkStockNum(shoppingCartList);

        //2.生成唯一的订单编号
        final String orderid = UUID.randomUUID().toString().replaceAll("-", "");
        //3.生成订单主表 (orders表)中的数据 看看有没有缺的   方法以遭遇元素的顺序拼接元素
        String skuNameList = shoppingCartList.stream().map(ShoppingCart::getSkuName).collect(Collectors.joining(","));
        orders.setUntitled(skuNameList);

        orders.setStatus(Constants.ORDER_WAIT_TO_PAY); // 设置订单为 待支付
        orders.setDeleteStatus(Constants.ORDER_DEFAULT_DELETE_FLAG);  // 逻辑删除标记

        orders.setCreateTime(new Date());
        orders.setUpdateTime(new Date());

        this.save(orders);

        final String orderId = orders.getOrderId();
        //4.生成订单明细表数据(orderItem表)
        //购物车中有几条数据,订单明细表中就有几条数据
// List<ShoppingCart>  --->  List<OrderItem>
        final List<OrderItem> orderItemList = shoppingCartList.stream()
                .map(shoppingCart ->{
                    final OrderItem orderItem = new OrderItem();

                    orderItem.setOrderId(orderId);

                    // 把 shoppingCart对象中同名的属性拷贝过来 BeanUtils.copyProperties
                    BeanUtils.copyProperties(shoppingCart,orderItem);

                    orderItem.setBuyCounts(Integer.valueOf(shoppingCart.getCartNum()));

                    orderItem.setTotalAmount(new BigDecimal(shoppingCart.getSellPrice()).multiply(new BigDecimal(Integer.valueOf(shoppingCart.getCartNum()))));

                    final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

                    try {
                        orderItem.setBasketDate(simpleDateFormat.parse(shoppingCart.getCartTime()));
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }

                    orderItem.setBuyTime(new Date());
                    orderItem.setIsComment(0);

                    return orderItem;

                }).collect(Collectors.toList());
        orderItemService.saveBatch(orderItemList);
        //5.删除用户购物车中的cids对应的数据
        shoppingCartService.removeBatchByIds(shoppingCartList);
        //6.跟微信支付平台交互,获取可以支付的url
        final String payUrl = WxPayUtils.getPayUrl(orderid);
        //7.组织返回map数据
        HashMap<String, Object> map = new HashMap<>();
        map.put("orderId", orderid);
        map.put("productNames",skuNameList);
        map.put("payUrl",payUrl);

        return map;
    }

    /**
     * 修改订单状态
     * @param oid
     * @return
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public String status(String oid) throws Exception {
    //1. 调用微信支付工具类查询订单的状态
    String status = WxPayUtils.queryOrder(oid);
 //如果订单状态不为空并且是SUCCESS
    if (status!=null &&status.equals("SUCCESS")){
        //那么更新状态和时间
        Orders orders = new Orders();
        orders.setOrderId(oid);
        orders.setStatus(Constants.PAY_OK_STATUS );
        orders.setUpdateTime(new Date());

        this.updateById(orders);

        return Constants.PAY_OK_STATUS;
    }
    return Constants.PAY_NOT_OK_STATUS;
    }

    /**
     * 校验库存
     *  先合并 sku_id相同的数据，得到总的购买量，再进行库存比较
     *  最后修改库存
     * @param shoppingCartList
     */
    private void checkStockNum(List<ShoppingCart> shoppingCartList) {
        //按照 sku_id进行分组操作
        Map<String, List<ShoppingCart>> skuIdMap = shoppingCartList.stream().collect(Collectors.groupingBy(ShoppingCart::getSkuId));
        //遍历
        for (Map.Entry<String, List<ShoppingCart>> entry : skuIdMap.entrySet()) {
            String key = entry.getKey();
            List<ShoppingCart> value = entry.getValue();

            Integer stock = value.get(0).getStock();

            //Collectors.summingInt 方法将流中的所有元素视为 int类型，并计算所有元素的总和
            Integer cartNum = value.stream().collect(Collectors.summingInt(ShoppingCart -> Integer.valueOf(ShoppingCart.getCartNum())));

            if (stock < cartNum) {
                throw new RuntimeException("库存不足");
            }
             // 扣减库存
            ProductSku sku = new ProductSku();
            sku.setSkuId(key);
            sku.setStock(stock - cartNum);
            productSkuService.updateById(sku);


        }
    }
}
